home *** CD-ROM | disk | FTP | other *** search
Text File | 2002-10-03 | 61.3 KB | 1,453 lines |
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111))))
-
-
-
- NNNNAAAAMMMMEEEE
- perlfaq8 - System Interaction ($Revision: 1.1 $, $Date: 2002/05/07
- 00:07:32 $)
-
- DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN
- This section of the Perl FAQ covers questions involving operating system
- interaction. This involves interprocess communication (IPC), control
- over the user-interface (keyboard, screen and pointing devices), and most
- anything else not related to data manipulation.
-
- Read the FAQs and documentation specific to the port of perl to your
- operating system (eg, the _p_e_r_l_v_m_s manpage, the _p_e_r_l_p_l_a_n_9 manpage, ...).
- These should contain more detailed information on the vagaries of your
- perl.
-
- HHHHoooowwww ddddoooo IIII ffffiiiinnnndddd oooouuuutttt wwwwhhhhiiiicccchhhh ooooppppeeeerrrraaaattttiiiinnnngggg ssssyyyysssstttteeeemmmm IIII''''mmmm rrrruuuunnnnnnnniiiinnnngggg uuuunnnnddddeeeerrrr????
-
- The $^O variable ($OSNAME if you use English) contains the operating
- system that your perl binary was built for.
-
- HHHHoooowwww ccccoooommmmeeee _e_x_e_c() doesn't return?
-
- Because that's what it does: it replaces your currently running program
- with a different one. If you want to keep going (as is probably the case
- if you're asking this question) use _s_y_s_t_e_m() instead.
-
- HHHHoooowwww ddddoooo IIII ddddoooo ffffaaaannnnccccyyyy ssssttttuuuuffffffff wwwwiiiitttthhhh tttthhhheeee kkkkeeeeyyyybbbbooooaaaarrrrdddd////ssssccccrrrreeeeeeeennnn////mmmmoooouuuusssseeee????
-
- How you access/control keyboards, screens, and pointing devices ("mice")
- is system-dependent. Try the following modules:
-
- Keyboard
-
- Term::Cap Standard perl distribution
- Term::ReadKey CPAN
- Term::ReadLine::Gnu CPAN
- Term::ReadLine::Perl CPAN
- Term::Screen CPAN
-
-
- Screen
-
- Term::Cap Standard perl distribution
- Curses CPAN
- Term::ANSIColor CPAN
-
-
- Mouse
-
- Tk CPAN
-
-
-
-
-
- PPPPaaaaggggeeee 1111
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111))))
-
-
-
- Some of these specific cases are shown below.
-
- HHHHoooowwww ddddoooo IIII pppprrrriiiinnnntttt ssssoooommmmeeeetttthhhhiiiinnnngggg oooouuuutttt iiiinnnn ccccoooolllloooorrrr????
-
- In general, you don't, because you don't know whether the recipient has a
- color-aware display device. If you know that they have an ANSI terminal
- that understands color, you can use the Term::ANSIColor module from CPAN:
-
- use Term::ANSIColor;
- print color("red"), "Stop!\n", color("reset");
- print color("green"), "Go!\n", color("reset");
-
- Or like this:
-
- use Term::ANSIColor qw(:constants);
- print RED, "Stop!\n", RESET;
- print GREEN, "Go!\n", RESET;
-
-
- HHHHoooowwww ddddoooo IIII rrrreeeeaaaadddd jjjjuuuusssstttt oooonnnneeee kkkkeeeeyyyy wwwwiiiitttthhhhoooouuuutttt wwwwaaaaiiiittttiiiinnnngggg ffffoooorrrr aaaa rrrreeeettttuuuurrrrnnnn kkkkeeeeyyyy????
-
- Controlling input buffering is a remarkably system-dependent matter. If
- most systems, you can just use the ssssttttttttyyyy command as shown in the getc
- entry in the _p_e_r_l_f_u_n_c manpage, but as you see, that's already getting you
- into portability snags.
-
- open(TTY, "+</dev/tty") or die "no tty: $!";
- system "stty cbreak </dev/tty >/dev/tty 2>&1";
- $key = getc(TTY); # perhaps this works
- # OR ELSE
- sysread(TTY, $key, 1); # probably this does
- system "stty -cbreak </dev/tty >/dev/tty 2>&1";
-
- The Term::ReadKey module from CPAN offers an easy-to-use interface that
- should be more efficient than shelling out to ssssttttttttyyyy for each key. It even
- includes limited support for Windows.
-
- use Term::ReadKey;
- ReadMode('cbreak');
- $key = ReadKey(0);
- ReadMode('normal');
-
- However, that requires that you have a working C compiler and can use it
- to build and install a CPAN module. Here's a solution using the standard
- POSIX module, which is already on your systems (assuming your system
- supports POSIX).
-
- use HotKey;
- $key = readkey();
-
- And here's the HotKey module, which hides the somewhat mystifying calls
- to manipulate the POSIX termios structures.
-
-
-
- PPPPaaaaggggeeee 2222
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111))))
-
-
-
- # HotKey.pm
- package HotKey;
-
- @ISA = qw(Exporter);
- @EXPORT = qw(cbreak cooked readkey);
-
- use strict;
- use POSIX qw(:termios_h);
- my ($term, $oterm, $echo, $noecho, $fd_stdin);
-
- $fd_stdin = fileno(STDIN);
- $term = POSIX::Termios->new();
- $term->getattr($fd_stdin);
- $oterm = $term->getlflag();
-
- $echo = ECHO | ECHOK | ICANON;
- $noecho = $oterm & ~$echo;
-
- sub cbreak {
- $term->setlflag($noecho); # ok, so i don't want echo either
- $term->setcc(VTIME, 1);
- $term->setattr($fd_stdin, TCSANOW);
- }
-
- sub cooked {
- $term->setlflag($oterm);
- $term->setcc(VTIME, 0);
- $term->setattr($fd_stdin, TCSANOW);
- }
-
- sub readkey {
- my $key = '';
- cbreak();
- sysread(STDIN, $key, 1);
- cooked();
- return $key;
- }
-
- END { cooked() }
-
- 1;
-
-
- HHHHoooowwww ddddoooo IIII cccchhhheeeecccckkkk wwwwhhhheeeetttthhhheeeerrrr iiiinnnnppppuuuutttt iiiissss rrrreeeeaaaaddddyyyy oooonnnn tttthhhheeee kkkkeeeeyyyybbbbooooaaaarrrrdddd????
-
- The easiest way to do this is to read a key in nonblocking mode with the
- Term::ReadKey module from CPAN, passing it an argument of -1 to indicate
- not to block:
-
- use Term::ReadKey;
-
- ReadMode('cbreak');
-
-
-
- PPPPaaaaggggeeee 3333
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111))))
-
-
-
- if (defined ($char = ReadKey(-1)) ) {
- # input was waiting and it was $char
- } else {
- # no input was waiting
- }
-
- ReadMode('normal'); # restore normal tty settings
-
-
- HHHHoooowwww ddddoooo IIII cccclllleeeeaaaarrrr tttthhhheeee ssssccccrrrreeeeeeeennnn????
-
- If you only have to so infrequently, use system:
-
- system("clear");
-
- If you have to do this a lot, save the clear string so you can print it
- 100 times without calling a program 100 times:
-
- $clear_string = `clear`;
- print $clear_string;
-
- If you're planning on doing other screen manipulations, like cursor
- positions, etc, you might wish to use Term::Cap module:
-
- use Term::Cap;
- $terminal = Term::Cap->Tgetent( {OSPEED => 9600} );
- $clear_string = $terminal->Tputs('cl');
-
-
- HHHHoooowwww ddddoooo IIII ggggeeeetttt tttthhhheeee ssssccccrrrreeeeeeeennnn ssssiiiizzzzeeee????
-
- If you have Term::ReadKey module installed from CPAN, you can use it to
- fetch the width and height in characters and in pixels:
-
- use Term::ReadKey;
- ($wchar, $hchar, $wpixels, $hpixels) = GetTerminalSize();
-
- This is more portable than the raw ioctl, but not as illustrative:
-
- require 'sys/ioctl.ph';
- die "no TIOCGWINSZ " unless defined &TIOCGWINSZ;
- open(TTY, "+</dev/tty") or die "No tty: $!";
- unless (ioctl(TTY, &TIOCGWINSZ, $winsize='')) {
- die sprintf "$0: ioctl TIOCGWINSZ (%08x: $!)\n", &TIOCGWINSZ;
- }
- ($row, $col, $xpixel, $ypixel) = unpack('S4', $winsize);
- print "(row,col) = ($row,$col)";
- print " (xpixel,ypixel) = ($xpixel,$ypixel)" if $xpixel || $ypixel;
- print "\n";
-
-
-
-
-
-
- PPPPaaaaggggeeee 4444
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111))))
-
-
-
- HHHHoooowwww ddddoooo IIII aaaasssskkkk tttthhhheeee uuuusssseeeerrrr ffffoooorrrr aaaa ppppaaaasssssssswwwwoooorrrrdddd????
-
- (This question has nothing to do with the web. See a different FAQ for
- that.)
-
- There's an example of this in the crypt entry in the _p_e_r_l_f_u_n_c manpage).
- First, you put the terminal into "no echo" mode, then just read the
- password normally. You may do this with an old-style _i_o_c_t_l() function,
- POSIX terminal control (see the _P_O_S_I_X manpage, and Chapter 7 of the
- Camel), or a call to the ssssttttttttyyyy program, with varying degrees of
- portability.
-
- You can also do this for most systems using the Term::ReadKey module from
- CPAN, which is easier to use and in theory more portable.
-
- use Term::ReadKey;
-
- ReadMode('noecho');
- $password = ReadLine(0);
-
-
- HHHHoooowwww ddddoooo IIII rrrreeeeaaaadddd aaaannnndddd wwwwrrrriiiitttteeee tttthhhheeee sssseeeerrrriiiiaaaallll ppppoooorrrrtttt????
-
- This depends on which operating system your program is running on. In
- the case of Unix, the serial ports will be accessible through files in
- /dev; on other systems, the devices names will doubtless differ. Several
- problem areas common to all device interaction are the following
-
- lockfiles
- Your system may use lockfiles to control multiple access. Make sure
- you follow the correct protocol. Unpredictable behaviour can result
- from multiple processes reading from one device.
-
- open mode
- If you expect to use both read and write operations on the device,
- you'll have to open it for update (see the section on _o_p_e_n in the
- _p_e_r_l_f_u_n_c manpage for details). You may wish to open it without
- running the risk of blocking by using _s_y_s_o_p_e_n() and
- O_RDWR|O_NDELAY|O_NOCTTY from the Fcntl module (part of the standard
- perl distribution). See the section on _s_y_s_o_p_e_n in the _p_e_r_l_f_u_n_c
- manpage for more on this approach.
-
- end of line
- Some devices will be expecting a "\r" at the end of each line rather
- than a "\n". In some ports of perl, "\r" and "\n" are different from
- their usual (Unix) ASCII values of "\012" and "\015". You may have
- to give the numeric values you want directly, using octal ("\015"),
- hex ("0x0D"), or as a control-character specification ("\cM").
-
- print DEV "atv1\012"; # wrong, for some devices
- print DEV "atv1\015"; # right, for some devices
-
-
-
-
- PPPPaaaaggggeeee 5555
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111))))
-
-
-
- Even though with normal text files, a "\n" will do the trick, there
- is still no unified scheme for terminating a line that is portable
- between Unix, DOS/Win, and Macintosh, except to terminate _A_L_L line
- ends with "\015\012", and strip what you don't need from the output.
- This applies especially to socket I/O and autoflushing, discussed
- next.
-
- flushing output
- If you expect characters to get to your device when you _p_r_i_n_t() them,
- you'll want to autoflush that filehandle. You can use _s_e_l_e_c_t() and
- the $| variable to control autoflushing (see the section on $| in the
- _p_e_r_l_v_a_r manpage and the select entry in the _p_e_r_l_f_u_n_c manpage):
-
- $oldh = select(DEV);
- $| = 1;
- select($oldh);
-
- You'll also see code that does this without a temporary variable, as
- in
-
- select((select(DEV), $| = 1)[0]);
-
- Or if you don't mind pulling in a few thousand lines of code just
- because you're afraid of a little $| variable:
-
- use IO::Handle;
- DEV->autoflush(1);
-
- As mentioned in the previous item, this still doesn't work when using
- socket I/O between Unix and Macintosh. You'll need to hardcode your
- line terminators, in that case.
-
- non-blocking input
- If you are doing a blocking _r_e_a_d() or _s_y_s_r_e_a_d(), you'll have to
- arrange for an alarm handler to provide a timeout (see the alarm
- entry in the _p_e_r_l_f_u_n_c manpage). If you have a non-blocking open,
- you'll likely have a non-blocking read, which means you may have to
- use a 4-arg _s_e_l_e_c_t() to determine whether I/O is ready on that device
- (see the section on _s_e_l_e_c_t in the _p_e_r_l_f_u_n_c manpage.
-
- While trying to read from his caller-id box, the notorious Jamie Zawinski
- <jwz@netscape.com>, after much gnashing of teeth and fighting with
- sysread, sysopen, POSIX's tcgetattr business, and various other functions
- that go bump in the night, finally came up with this:
-
-
-
-
-
-
-
-
-
-
-
- PPPPaaaaggggeeee 6666
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111))))
-
-
-
- sub open_modem {
- use IPC::Open2;
- my $stty = `/bin/stty -g`;
- open2( \*MODEM_IN, \*MODEM_OUT, "cu -l$modem_device -s2400 2>&1");
- # starting cu hoses /dev/tty's stty settings, even when it has
- # been opened on a pipe...
- system("/bin/stty $stty");
- $_ = <MODEM_IN>;
- chop;
- if ( !m/^Connected/ ) {
- print STDERR "$0: cu printed `$_' instead of `Connected'\n";
- }
- }
-
-
- HHHHoooowwww ddddoooo IIII ddddeeeeccccooooddddeeee eeeennnnccccrrrryyyypppptttteeeedddd ppppaaaasssssssswwwwoooorrrrdddd ffffiiiilllleeeessss????
-
- You spend lots and lots of money on dedicated hardware, but this is bound
- to get you talked about.
-
- Seriously, you can't if they are Unix password files - the Unix password
- system employs one-way encryption. It's more like hashing than
- encryption. The best you can check is whether something else hashes to
- the same string. You can't turn a hash back into the original string.
- Programs like Crack can forcibly (and intelligently) try to guess
- passwords, but don't (can't) guarantee quick success.
-
- If you're worried about users selecting bad passwords, you should
- proactively check when they try to change their password (by modifying
- _p_a_s_s_w_d(1), for example).
-
- HHHHoooowwww ddddoooo IIII ssssttttaaaarrrrtttt aaaa pppprrrroooocccceeeessssssss iiiinnnn tttthhhheeee bbbbaaaacccckkkkggggrrrroooouuuunnnndddd????
-
- You could use
-
- system("cmd &")
-
- or you could use fork as documented in the section on _f_o_r_k in the
- _p_e_r_l_f_u_n_c manpage, with further examples in the _p_e_r_l_i_p_c manpage. Some
- things to be aware of, if you're on a Unix-like system:
-
- STDIN, STDOUT, and STDERR are shared
- Both the main process and the backgrounded one (the "child" process)
- share the same STDIN, STDOUT and STDERR filehandles. If both try to
- access them at once, strange things can happen. You may want to
- close or reopen these for the child. You can get around this with
- opening a pipe (see the section on _o_p_e_n in the _p_e_r_l_f_u_n_c manpage) but
- on some systems this means that the child process cannot outlive the
- parent.
-
-
-
-
-
-
- PPPPaaaaggggeeee 7777
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111))))
-
-
-
- Signals
- You'll have to catch the SIGCHLD signal, and possibly SIGPIPE too.
- SIGCHLD is sent when the backgrounded process finishes. SIGPIPE is
- sent when you write to a filehandle whose child process has closed
- (an untrapped SIGPIPE can cause your program to silently die). This
- is not an issue with system("cmd&").
-
- Zombies
- You have to be prepared to "reap" the child process when it finishes
-
- $SIG{CHLD} = sub { wait };
-
- See the section on _S_i_g_n_a_l_s in the _p_e_r_l_i_p_c manpage for other examples
- of code to do this. Zombies are not an issue with system("prog &").
-
- HHHHoooowwww ddddoooo IIII ttttrrrraaaapppp ccccoooonnnnttttrrrroooollll cccchhhhaaaarrrraaaacccctttteeeerrrrssss////ssssiiiiggggnnnnaaaallllssss????
-
- You don't actually "trap" a control character. Instead, that character
- generates a signal which is sent to your terminal's currently
- foregrounded process group, which you then trap in your process. Signals
- are documented in the section on _S_i_g_n_a_l_s in the _p_e_r_l_i_p_c manpage and
- chapter 6 of the Camel.
-
- Be warned that very few C libraries are re-entrant. Therefore, if you
- attempt to _p_r_i_n_t() in a handler that got invoked during another stdio
- operation your internal structures will likely be in an inconsistent
- state, and your program will dump core. You can sometimes avoid this by
- using _s_y_s_w_r_i_t_e() instead of _p_r_i_n_t().
-
- Unless you're exceedingly careful, the only safe things to do inside a
- signal handler are: set a variable and exit. And in the first case, you
- should only set a variable in such a way that _m_a_l_l_o_c() is not called (eg,
- by setting a variable that already has a value).
-
- For example:
-
- $Interrupted = 0; # to ensure it has a value
- $SIG{INT} = sub {
- $Interrupted++;
- syswrite(STDERR, "ouch\n", 5);
- }
-
- However, because syscalls restart by default, you'll find that if you're
- in a "slow" call, such as <FH>, _r_e_a_d(), _c_o_n_n_e_c_t(), or _w_a_i_t(), that the
- only way to terminate them is by "longjumping" out; that is, by raising
- an exception. See the time-out handler for a blocking _f_l_o_c_k() in the
- section on _S_i_g_n_a_l_s in the _p_e_r_l_i_p_c manpage or chapter 6 of the Camel.
-
- HHHHoooowwww ddddoooo IIII mmmmooooddddiiiiffffyyyy tttthhhheeee sssshhhhaaaaddddoooowwww ppppaaaasssssssswwwwoooorrrrdddd ffffiiiilllleeee oooonnnn aaaa UUUUnnnniiiixxxx ssssyyyysssstttteeeemmmm????
-
-
-
-
-
-
- PPPPaaaaggggeeee 8888
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111))))
-
-
-
- If perl was installed correctly, and your shadow library was written
- properly, the getpw*() functions described in the _p_e_r_l_f_u_n_c manpage should
- in theory provide (read-only) access to entries in the shadow password
- file. To change the file, make a new shadow password file (the format
- varies from system to system - see the _p_a_s_s_w_d(_5) manpage for specifics)
- and use _p_w_d__m_k_d_b(8) to install it (see the _p_w_d__m_k_d_b(_5) manpage for more
- details).
-
- HHHHoooowwww ddddoooo IIII sssseeeetttt tttthhhheeee ttttiiiimmmmeeee aaaannnndddd ddddaaaatttteeee????
-
- Assuming you're running under sufficient permissions, you should be able
- to set the system-wide date and time by running the _d_a_t_e(1) program.
- (There is no way to set the time and date on a per-process basis.) This
- mechanism will work for Unix, MS-DOS, Windows, and NT; the VMS equivalent
- is set time.
-
- However, if all you want to do is change your timezone, you can probably
- get away with setting an environment variable:
-
- $ENV{TZ} = "MST7MDT"; # unixish
- $ENV{'SYS$TIMEZONE_DIFFERENTIAL'}="-5" # vms
- system "trn comp.lang.perl.misc";
-
-
- HHHHoooowwww ccccaaaannnn IIII _s_l_e_e_p() or _a_l_a_r_m() for under a second?
-
- If you want finer granularity than the 1 second that the _s_l_e_e_p() function
- provides, the easiest way is to use the _s_e_l_e_c_t() function as documented
- in the section on _s_e_l_e_c_t in the _p_e_r_l_f_u_n_c manpage. If your system has
- itimers and _s_y_s_c_a_l_l() support, you can check out the old example in
- http://www.perl.com/CPAN/doc/misc/ancient/tutorial/eg/itimers.pl .
-
- HHHHoooowwww ccccaaaannnn IIII mmmmeeeeaaaassssuuuurrrreeee ttttiiiimmmmeeee uuuunnnnddddeeeerrrr aaaa sssseeeeccccoooonnnndddd????
-
- In general, you may not be able to. The Time::HiRes module (available
- from CPAN) provides this functionality for some systems.
-
- In general, you may not be able to. But if your system supports both the
- _s_y_s_c_a_l_l() function in Perl as well as a system call like _g_e_t_t_i_m_e_o_f_d_a_y(2),
- then you may be able to do something like this:
-
- require 'sys/syscall.ph';
-
- $TIMEVAL_T = "LL";
-
- $done = $start = pack($TIMEVAL_T, ());
-
- syscall( &SYS_gettimeofday, $start, 0)) != -1
- or die "gettimeofday: $!";
-
-
-
-
-
-
- PPPPaaaaggggeeee 9999
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111))))
-
-
-
- ##########################
- # DO YOUR OPERATION HERE #
- ##########################
-
- syscall( &SYS_gettimeofday, $done, 0) != -1
- or die "gettimeofday: $!";
-
- @start = unpack($TIMEVAL_T, $start);
- @done = unpack($TIMEVAL_T, $done);
-
- # fix microseconds
- for ($done[1], $start[1]) { $_ /= 1_000_000 }
-
- $delta_time = sprintf "%.4f", ($done[0] + $done[1] )
- -
- ($start[0] + $start[1] );
-
-
- HHHHoooowwww ccccaaaannnn IIII ddddoooo aaaannnn _a_t_e_x_i_t() or _s_e_t_j_m_p()/_l_o_n_g_j_m_p()? (Exception handling)
-
- Release 5 of Perl added the END block, which can be used to simulate
- _a_t_e_x_i_t(). Each package's END block is called when the program or thread
- ends (see the _p_e_r_l_m_o_d manpage manpage for more details).
-
- For example, you can use this to make sure your filter program managed to
- finish its output without filling up the disk:
-
- END {
- close(STDOUT) || die "stdout close failed: $!";
- }
-
- The END block isn't called when untrapped signals kill the program,
- though, so if you use END blocks you should also use
-
- use sigtrap qw(die normal-signals);
-
- Perl's exception-handling mechanism is its _e_v_a_l() operator. You can use
- _e_v_a_l() as setjmp and _d_i_e() as longjmp. For details of this, see the
- section on signals, especially the time-out handler for a blocking
- _f_l_o_c_k() in the section on _S_i_g_n_a_l_s in the _p_e_r_l_i_p_c manpage and chapter 6 of
- the Camel.
-
- If exception handling is all you're interested in, try the exceptions.pl
- library (part of the standard perl distribution).
-
- If you want the _a_t_e_x_i_t() syntax (and an _r_m_e_x_i_t() as well), try the AtExit
- module available from CPAN.
-
- WWWWhhhhyyyy ddddooooeeeessssnnnn''''tttt mmmmyyyy ssssoooocccckkkkeeeettttssss pppprrrrooooggggrrrraaaammmm wwwwoooorrrrkkkk uuuunnnnddddeeeerrrr SSSSyyyysssstttteeeemmmm VVVV ((((SSSSoooollllaaaarrrriiiissss))))???? WWWWhhhhaaaatttt ddddooooeeeessss
- tttthhhheeee eeeerrrrrrrroooorrrr mmmmeeeessssssssaaaaggggeeee """"PPPPrrrroooottttooooccccoooollll nnnnooootttt ssssuuuuppppppppoooorrrrtttteeeedddd"""" mmmmeeeeaaaannnn????
-
-
-
-
-
- PPPPaaaaggggeeee 11110000
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111))))
-
-
-
- Some Sys-V based systems, notably Solaris 2.X, redefined some of the
- standard socket constants. Since these were constant across all
- architectures, they were often hardwired into perl code. The proper way
- to deal with this is to "use Socket" to get the correct values.
-
- Note that even though SunOS and Solaris are binary compatible, these
- values are different. Go figure.
-
- HHHHoooowwww ccccaaaannnn IIII ccccaaaallllllll mmmmyyyy ssssyyyysssstttteeeemmmm''''ssss uuuunnnniiiiqqqquuuueeee CCCC ffffuuuunnnnccccttttiiiioooonnnnssss ffffrrrroooommmm PPPPeeeerrrrllll????
-
- In most cases, you write an external module to do it - see the answer to
- "Where can I learn about linking C with Perl? [h2xs, xsubpp]". However,
- if the function is a system call, and your system supports _s_y_s_c_a_l_l(), you
- can use the syscall function (documented in the _p_e_r_l_f_u_n_c manpage).
-
- Remember to check the modules that came with your distribution, and CPAN
- as well - someone may already have written a module to do it.
-
- WWWWhhhheeeerrrreeee ddddoooo IIII ggggeeeetttt tttthhhheeee iiiinnnncccclllluuuuddddeeee ffffiiiilllleeeessss ttttoooo ddddoooo _i_o_c_t_l() or _s_y_s_c_a_l_l()?
-
- Historically, these would be generated by the h2ph tool, part of the
- standard perl distribution. This program converts _c_p_p(1) directives in C
- header files to files containing subroutine definitions, like
- &SYS_getitimer, which you can use as arguments to your functions. It
- doesn't work perfectly, but it usually gets most of the job done. Simple
- files like _e_r_r_n_o._h, _s_y_s_c_a_l_l._h, and _s_o_c_k_e_t._h were fine, but the hard ones
- like _i_o_c_t_l._h nearly always need to hand-edited. Here's how to install
- the *.ph files:
-
- 1. become super-user
- 2. cd /usr/include
- 3. h2ph *.h */*.h
-
- If your system supports dynamic loading, for reasons of portability and
- sanity you probably ought to use h2xs (also part of the standard perl
- distribution). This tool converts C header files to Perl extensions.
- See the _p_e_r_l_x_s_t_u_t manpage for how to get started with h2xs.
-
- If your system doesn't support dynamic loading, you still probably ought
- to use h2xs. See the _p_e_r_l_x_s_t_u_t manpage and the _E_x_t_U_t_i_l_s::_M_a_k_e_M_a_k_e_r
- manpage for more information (in brief, just use mmmmaaaakkkkeeee ppppeeeerrrrllll instead of a
- plain mmmmaaaakkkkeeee to rebuild perl with a new static extension).
-
- WWWWhhhhyyyy ddddoooo sssseeeettttuuuuiiiidddd ppppeeeerrrrllll ssssccccrrrriiiippppttttssss ccccoooommmmppppllllaaaaiiiinnnn aaaabbbboooouuuutttt kkkkeeeerrrrnnnneeeellll pppprrrroooobbbblllleeeemmmmssss????
-
- Some operating systems have bugs in the kernel that make setuid scripts
- inherently insecure. Perl gives you a number of options (described in
- the _p_e_r_l_s_e_c manpage) to work around such systems.
-
-
-
-
-
-
-
- PPPPaaaaggggeeee 11111111
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111))))
-
-
-
- HHHHoooowwww ccccaaaannnn IIII ooooppppeeeennnn aaaa ppppiiiippppeeee bbbbooootttthhhh ttttoooo aaaannnndddd ffffrrrroooommmm aaaa ccccoooommmmmmmmaaaannnndddd????
-
- The IPC::Open2 module (part of the standard perl distribution) is an
- easy-to-use approach that internally uses _p_i_p_e(), _f_o_r_k(), and _e_x_e_c() to
- do the job. Make sure you read the deadlock warnings in its
- documentation, though (see the _I_P_C::_O_p_e_n_2 manpage). See the section on
- _B_i_d_i_r_e_c_t_i_o_n_a_l _C_o_m_m_u_n_i_c_a_t_i_o_n _w_i_t_h _A_n_o_t_h_e_r _P_r_o_c_e_s_s in the _p_e_r_l_i_p_c manpage
- and the section on _B_i_d_i_r_e_c_t_i_o_n_a_l _C_o_m_m_u_n_i_c_a_t_i_o_n _w_i_t_h _Y_o_u_r_s_e_l_f in the
- _p_e_r_l_i_p_c manpage
-
- You may also use the IPC::Open3 module (part of the standard perl
- distribution), but be warned that it has a different order of arguments
- from IPC::Open2 (see the _I_P_C::_O_p_e_n_3 manpage).
-
- WWWWhhhhyyyy ccccaaaannnn''''tttt IIII ggggeeeetttt tttthhhheeee oooouuuuttttppppuuuutttt ooooffff aaaa ccccoooommmmmmmmaaaannnndddd wwwwiiiitttthhhh _s_y_s_t_e_m()?
-
- You're confusing the purpose of _s_y_s_t_e_m() and backticks (``). _s_y_s_t_e_m()
- runs a command and returns exit status information (as a 16 bit value:
- the low 7 bits are the signal the process died from, if any, and the high
- 8 bits are the actual exit value). Backticks (``) run a command and
- return what it sent to STDOUT.
-
- $exit_status = system("mail-users");
- $output_string = `ls`;
-
-
- HHHHoooowwww ccccaaaannnn IIII ccccaaaappppttttuuuurrrreeee SSSSTTTTDDDDEEEERRRRRRRR ffffrrrroooommmm aaaannnn eeeexxxxtttteeeerrrrnnnnaaaallll ccccoooommmmmmmmaaaannnndddd????
-
- There are three basic ways of running external commands:
-
- system $cmd; # using system()
- $output = `$cmd`; # using backticks (``)
- open (PIPE, "cmd |"); # using open()
-
- With _s_y_s_t_e_m(), both STDOUT and STDERR will go the same place as the
- script's versions of these, unless the command redirects them. Backticks
- and _o_p_e_n() read oooonnnnllllyyyy the STDOUT of your command.
-
- With any of these, you can change file descriptors before the call:
-
- open(STDOUT, ">logfile");
- system("ls");
-
- or you can use Bourne shell file-descriptor redirection:
-
- $output = `$cmd 2>some_file`;
- open (PIPE, "cmd 2>some_file |");
-
- You can also use file-descriptor redirection to make STDERR a duplicate
- of STDOUT:
-
-
-
-
-
- PPPPaaaaggggeeee 11112222
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111))))
-
-
-
- $output = `$cmd 2>&1`;
- open (PIPE, "cmd 2>&1 |");
-
- Note that you _c_a_n_n_o_t simply open STDERR to be a dup of STDOUT in your
- Perl program and avoid calling the shell to do the redirection. This
- doesn't work:
-
- open(STDERR, ">&STDOUT");
- $alloutput = `cmd args`; # stderr still escapes
-
- This fails because the _o_p_e_n() makes STDERR go to where STDOUT was going
- at the time of the _o_p_e_n(). The backticks then make STDOUT go to a
- string, but don't change STDERR (which still goes to the old STDOUT).
-
- Note that you _m_u_s_t use Bourne shell (_s_h(1)) redirection syntax in
- backticks, not _c_s_h(1)! Details on why Perl's _s_y_s_t_e_m() and backtick and
- pipe opens all use the Bourne shell are in
- http://www.perl.com/CPAN/doc/FMTEYEWTK/versus/csh.whynot . To capture a
- command's STDERR and STDOUT together:
-
- $output = `cmd 2>&1`; # either with backticks
- $pid = open(PH, "cmd 2>&1 |"); # or with an open pipe
- while (<PH>) { } # plus a read
-
- To capture a command's STDOUT but discard its STDERR:
-
- $output = `cmd 2>/dev/null`; # either with backticks
- $pid = open(PH, "cmd 2>/dev/null |"); # or with an open pipe
- while (<PH>) { } # plus a read
-
- To capture a command's STDERR but discard its STDOUT:
-
- $output = `cmd 2>&1 1>/dev/null`; # either with backticks
- $pid = open(PH, "cmd 2>&1 1>/dev/null |"); # or with an open pipe
- while (<PH>) { } # plus a read
-
- To exchange a command's STDOUT and STDERR in order to capture the STDERR
- but leave its STDOUT to come out our old STDERR:
-
- $output = `cmd 3>&1 1>&2 2>&3 3>&-`; # either with backticks
- $pid = open(PH, "cmd 3>&1 1>&2 2>&3 3>&-|");# or with an open pipe
- while (<PH>) { } # plus a read
-
- To read both a command's STDOUT and its STDERR separately, it's easiest
- and safest to redirect them separately to files, and then read from those
- files when the program is done:
-
- system("program args 1>/tmp/program.stdout 2>/tmp/program.stderr");
-
- Ordering is important in all these examples. That's because the shell
- processes file descriptor redirections in strictly left to right order.
-
-
-
-
- PPPPaaaaggggeeee 11113333
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111))))
-
-
-
- system("prog args 1>tmpfile 2>&1");
- system("prog args 2>&1 1>tmpfile");
-
- The first command sends both standard out and standard error to the
- temporary file. The second command sends only the old standard output
- there, and the old standard error shows up on the old standard out.
-
- WWWWhhhhyyyy ddddooooeeeessssnnnn''''tttt _o_p_e_n() return an error when a pipe open fails?
-
- It does, but probably not how you expect it to. On systems that follow
- the standard _f_o_r_k()/_e_x_e_c() paradigm (such as Unix), it works like this:
- _o_p_e_n() causes a _f_o_r_k(). In the parent, _o_p_e_n() returns with the process
- ID of the child. The child _e_x_e_c()s the command to be piped to/from. The
- parent can't know whether the _e_x_e_c() was successful or not - all it can
- return is whether the _f_o_r_k() succeeded or not. To find out if the
- command succeeded, you have to catch SIGCHLD and _w_a_i_t() to get the exit
- status. You should also catch SIGPIPE if you're writing to the child --
- you may not have found out the _e_x_e_c() failed by the time you write. This
- is documented in the _p_e_r_l_i_p_c manpage.
-
- On systems that follow the _s_p_a_w_n() paradigm, _o_p_e_n() _m_i_g_h_t do what you
- expect - unless perl uses a shell to start your command. In this case the
- _f_o_r_k()/_e_x_e_c() description still applies.
-
- WWWWhhhhaaaatttt''''ssss wwwwrrrroooonnnngggg wwwwiiiitttthhhh uuuussssiiiinnnngggg bbbbaaaacccckkkkttttiiiicccckkkkssss iiiinnnn aaaa vvvvooooiiiidddd ccccoooonnnntttteeeexxxxtttt????
-
- Strictly speaking, nothing. Stylistically speaking, it's not a good way
- to write maintainable code because backticks have a (potentially
- humungous) return value, and you're ignoring it. It's may also not be
- very efficient, because you have to read in all the lines of output,
- allocate memory for them, and then throw it away. Too often people are
- lulled to writing:
-
- `cp file file.bak`;
-
- And now they think "Hey, I'll just always use backticks to run programs."
- Bad idea: backticks are for capturing a program's output; the _s_y_s_t_e_m()
- function is for running programs.
-
- Consider this line:
-
- `cat /etc/termcap`;
-
- You haven't assigned the output anywhere, so it just wastes memory (for a
- little while). Plus you forgot to check $? to see whether the program
- even ran correctly. Even if you wrote
-
- print `cat /etc/termcap`;
-
- In most cases, this could and probably should be written as
-
-
-
-
-
- PPPPaaaaggggeeee 11114444
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111))))
-
-
-
- system("cat /etc/termcap") == 0
- or die "cat program failed!";
-
- Which will get the output quickly (as its generated, instead of only at
- the end) and also check the return value.
-
- _s_y_s_t_e_m() also provides direct control over whether shell wildcard
- processing may take place, whereas backticks do not.
-
- HHHHoooowwww ccccaaaannnn IIII ccccaaaallllllll bbbbaaaacccckkkkttttiiiicccckkkkssss wwwwiiiitttthhhhoooouuuutttt sssshhhheeeellllllll pppprrrroooocccceeeessssssssiiiinnnngggg????
-
- This is a bit tricky. Instead of writing
-
- @ok = `grep @opts '$search_string' @filenames`;
-
- You have to do this:
-
- my @ok = ();
- if (open(GREP, "-|")) {
- while (<GREP>) {
- chomp;
- push(@ok, $_);
- }
- close GREP;
- } else {
- exec 'grep', @opts, $search_string, @filenames;
- }
-
- Just as with _s_y_s_t_e_m(), no shell escapes happen when you _e_x_e_c() a list.
-
- There are more examples of this the section on _S_a_f_e _P_i_p_e _O_p_e_n_s in the
- _p_e_r_l_i_p_c manpage.
-
- WWWWhhhhyyyy ccccaaaannnn''''tttt mmmmyyyy ssssccccrrrriiiipppptttt rrrreeeeaaaadddd ffffrrrroooommmm SSSSTTTTDDDDIIIINNNN aaaafffftttteeeerrrr IIII ggggaaaavvvveeee iiiitttt EEEEOOOOFFFF ((((^^^^DDDD oooonnnn UUUUnnnniiiixxxx,,,, ^^^^ZZZZ
- oooonnnn MMMMSSSS----DDDDOOOOSSSS))))????
-
- Because some stdio's set error and eof flags that need clearing. The
- POSIX module defines _c_l_e_a_r_e_r_r() that you can use. That is the
- technically correct way to do it. Here are some less reliable
- workarounds:
-
- 1 Try keeping around the seekpointer and go there, like this:
-
- $where = tell(LOG);
- seek(LOG, $where, 0);
-
-
- 2 If that doesn't work, try seeking to a different part of the file and
- then back.
-
-
-
-
-
-
- PPPPaaaaggggeeee 11115555
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111))))
-
-
-
- 3 If that doesn't work, try seeking to a different part of the file,
- reading something, and then seeking back.
-
- 4 If that doesn't work, give up on your stdio package and use sysread.
-
- HHHHoooowwww ccccaaaannnn IIII ccccoooonnnnvvvveeeerrrrtttt mmmmyyyy sssshhhheeeellllllll ssssccccrrrriiiipppptttt ttttoooo ppppeeeerrrrllll????
-
- Learn Perl and rewrite it. Seriously, there's no simple converter.
- Things that are awkward to do in the shell are easy to do in Perl, and
- this very awkwardness is what would make a shell->perl converter nigh-on
- impossible to write. By rewriting it, you'll think about what you're
- really trying to do, and hopefully will escape the shell's pipeline
- datastream paradigm, which while convenient for some matters, causes many
- inefficiencies.
-
- CCCCaaaannnn IIII uuuusssseeee ppppeeeerrrrllll ttttoooo rrrruuuunnnn aaaa tttteeeellllnnnneeeetttt oooorrrr ffffttttpppp sssseeeessssssssiiiioooonnnn????
-
- Try the Net::FTP, TCP::Client, and Net::Telnet modules (available from
- CPAN). http://www.perl.com/CPAN/scripts/netstuff/telnet.emul.shar will
- also help for emulating the telnet protocol, but Net::Telnet is quite
- probably easier to use..
-
- If all you want to do is pretend to be telnet but don't need the initial
- telnet handshaking, then the standard dual-process approach will suffice:
-
- use IO::Socket; # new in 5.004
- $handle = IO::Socket::INET->new('www.perl.com:80')
- || die "can't connect to port 80 on www.perl.com: $!";
- $handle->autoflush(1);
- if (fork()) { # XXX: undef means failure
- select($handle);
- print while <STDIN>; # everything from stdin to socket
- } else {
- print while <$handle>; # everything from socket to stdout
- }
- close $handle;
- exit;
-
-
- HHHHoooowwww ccccaaaannnn IIII wwwwrrrriiiitttteeee eeeexxxxppppeeeecccctttt iiiinnnn PPPPeeeerrrrllll????
-
- Once upon a time, there was a library called chat2.pl (part of the
- standard perl distribution), which never really got finished. If you
- find it somewhere, _d_o_n'_t _u_s_e _i_t. These days, your best bet is to look at
- the Expect module available from CPAN, which also requires two other
- modules from CPAN, IO::Pty and IO::Stty.
-
- IIIIssss tttthhhheeeerrrreeee aaaa wwwwaaaayyyy ttttoooo hhhhiiiiddddeeee ppppeeeerrrrllll''''ssss ccccoooommmmmmmmaaaannnndddd lllliiiinnnneeee ffffrrrroooommmm pppprrrrooooggggrrrraaaammmmssss ssssuuuucccchhhh aaaassss """"ppppssss""""????
-
- First of all note that if you're doing this for security reasons (to
- avoid people seeing passwords, for example) then you should rewrite your
- program so that critical information is never given as an argument.
-
-
-
- PPPPaaaaggggeeee 11116666
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111))))
-
-
-
- Hiding the arguments won't make your program completely secure.
-
- To actually alter the visible command line, you can assign to the
- variable $0 as documented in the _p_e_r_l_v_a_r manpage. This won't work on all
- operating systems, though. Daemon programs like sendmail place their
- state there, as in:
-
- $0 = "orcus [accepting connections]";
-
-
- IIII {{{{cccchhhhaaaannnnggggeeeedddd ddddiiiirrrreeeeccccttttoooorrrryyyy,,,, mmmmooooddddiiiiffffiiiieeeedddd mmmmyyyy eeeennnnvvvviiiirrrroooonnnnmmmmeeeennnntttt}}}} iiiinnnn aaaa ppppeeeerrrrllll ssssccccrrrriiiipppptttt.... HHHHoooowwww
- ccccoooommmmeeee tttthhhheeee cccchhhhaaaannnnggggeeee ddddiiiissssaaaappppppppeeeeaaaarrrreeeedddd wwwwhhhheeeennnn IIII eeeexxxxiiiitttteeeedddd tttthhhheeee ssssccccrrrriiiipppptttt???? HHHHoooowwww ddddoooo IIII ggggeeeetttt mmmmyyyy
- cccchhhhaaaannnnggggeeeessss ttttoooo bbbbeeee vvvviiiissssiiiibbbblllleeee????
-
- Unix
- In the strictest sense, it can't be done -- the script executes as a
- different process from the shell it was started from. Changes to a
- process are not reflected in its parent, only in its own children
- created after the change. There is shell magic that may allow you to
- fake it by _e_v_a_l()ing the script's output in your shell; check out the
- comp.unix.questions FAQ for details.
-
- HHHHoooowwww ddddoooo IIII cccclllloooosssseeee aaaa pppprrrroooocccceeeessssssss''''ssss ffffiiiilllleeeehhhhaaaannnnddddlllleeee wwwwiiiitttthhhhoooouuuutttt wwwwaaaaiiiittttiiiinnnngggg ffffoooorrrr iiiitttt ttttoooo ccccoooommmmpppplllleeeetttteeee????
-
- Assuming your system supports such things, just send an appropriate
- signal to the process (see the section on _k_i_l_l in the _p_e_r_l_f_u_n_c manpage.
- It's common to first send a TERM signal, wait a little bit, and then send
- a KILL signal to finish it off.
-
- HHHHoooowwww ddddoooo IIII ffffoooorrrrkkkk aaaa ddddaaaaeeeemmmmoooonnnn pppprrrroooocccceeeessssssss????
-
- If by daemon process you mean one that's detached (disassociated from its
- tty), then the following process is reported to work on most Unixish
- systems. Non-Unix users should check their Your_OS::Process module for
- other solutions.
-
- +o Open /dev/tty and use the the TIOCNOTTY ioctl on it. See the _t_t_y(_4)
- manpage for details. Or better yet, you can just use the
- _P_O_S_I_X::_s_e_t_s_i_d() function, so you don't have to worry about process
- groups.
-
- +o Change directory to /
-
- +o Reopen STDIN, STDOUT, and STDERR so they're not connected to the old
- tty.
-
- +o Background yourself like this:
-
- fork && exit;
-
-
-
-
-
-
- PPPPaaaaggggeeee 11117777
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111))))
-
-
-
- HHHHoooowwww ddddoooo IIII mmmmaaaakkkkeeee mmmmyyyy pppprrrrooooggggrrrraaaammmm rrrruuuunnnn wwwwiiiitttthhhh sssshhhh aaaannnndddd ccccsssshhhh????
-
- See the _e_g/_n_i_h script (part of the perl source distribution).
-
- HHHHoooowwww ddddoooo IIII ffffiiiinnnndddd oooouuuutttt iiiiffff IIII''''mmmm rrrruuuunnnnnnnniiiinnnngggg iiiinnnntttteeeerrrraaaaccccttttiiiivvvveeeellllyyyy oooorrrr nnnnooootttt????
-
- Good question. Sometimes -t STDIN and -t STDOUT can give clues,
- sometimes not.
-
- if (-t STDIN && -t STDOUT) {
- print "Now what? ";
- }
-
- On POSIX systems, you can test whether your own process group matches the
- current process group of your controlling terminal as follows:
-
- use POSIX qw/getpgrp tcgetpgrp/;
- open(TTY, "/dev/tty") or die $!;
- $tpgrp = tcgetpgrp(TTY);
- $pgrp = getpgrp();
- if ($tpgrp == $pgrp) {
- print "foreground\n";
- } else {
- print "background\n";
- }
-
-
- HHHHoooowwww ddddoooo IIII ttttiiiimmmmeeeeoooouuuutttt aaaa sssslllloooowwww eeeevvvveeeennnntttt????
-
- Use the _a_l_a_r_m() function, probably in conjunction with a signal handler,
- as documented the section on _S_i_g_n_a_l_s in the _p_e_r_l_i_p_c manpage and chapter 6
- of the Camel. You may instead use the more flexible Sys::AlarmCall
- module available from CPAN.
-
- HHHHoooowwww ddddoooo IIII sssseeeetttt CCCCPPPPUUUU lllliiiimmmmiiiittttssss????
-
- Use the BSD::Resource module from CPAN.
-
- HHHHoooowwww ddddoooo IIII aaaavvvvooooiiiidddd zzzzoooommmmbbbbiiiieeeessss oooonnnn aaaa UUUUnnnniiiixxxx ssssyyyysssstttteeeemmmm????
-
- Use the reaper code from the section on _S_i_g_n_a_l_s in the _p_e_r_l_i_p_c manpage to
- call _w_a_i_t() when a SIGCHLD is received, or else use the double-fork
- technique described in the fork entry in the _p_e_r_l_f_u_n_c manpage.
-
- HHHHoooowwww ddddoooo IIII uuuusssseeee aaaannnn SSSSQQQQLLLL ddddaaaattttaaaabbbbaaaasssseeee????
-
- There are a number of excellent interfaces to SQL databases. See the
- DBD::* modules available from http://www.perl.com/CPAN/modules/dbperl/DBD
- . A lot of information on this can be found at
- http://www.hermetica.com/technologia/perl/DBI/index.html .
-
-
-
-
-
- PPPPaaaaggggeeee 11118888
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111))))
-
-
-
- HHHHoooowwww ddddoooo IIII mmmmaaaakkkkeeee aaaa _s_y_s_t_e_m() exit on control-C?
-
- You can't. You need to imitate the _s_y_s_t_e_m() call (see the _p_e_r_l_i_p_c
- manpage for sample code) and then have a signal handler for the INT
- signal that passes the signal on to the subprocess. Or you can check for
- it:
-
- $rc = system($cmd);
- if ($rc & 127) { die "signal death" }
-
-
- HHHHoooowwww ddddoooo IIII ooooppppeeeennnn aaaa ffffiiiilllleeee wwwwiiiitttthhhhoooouuuutttt bbbblllloooocccckkkkiiiinnnngggg????
-
- If you're lucky enough to be using a system that supports non-blocking
- reads (most Unixish systems do), you need only to use the O_NDELAY or
- O_NONBLOCK flag from the Fcntl module in conjunction with _s_y_s_o_p_e_n():
-
- use Fcntl;
- sysopen(FH, "/tmp/somefile", O_WRONLY|O_NDELAY|O_CREAT, 0644)
- or die "can't open /tmp/somefile: $!":
-
-
- HHHHoooowwww ddddoooo IIII iiiinnnnssssttttaaaallllllll aaaa CCCCPPPPAAAANNNN mmmmoooodddduuuulllleeee????
-
- The easiest way is to have the CPAN module do it for you. This module
- comes with perl version 5.004 and later. To manually install the CPAN
- module, or any well-behaved CPAN module for that matter, follow these
- steps:
-
- 1 Unpack the source into a temporary area.
-
- 2
-
- perl Makefile.PL
-
-
- 3
-
- make
-
-
- 4
-
- make test
-
-
- 5
-
- make install
-
-
-
-
-
-
- PPPPaaaaggggeeee 11119999
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111))))
-
-
-
- If your version of perl is compiled without dynamic loading, then you
- just need to replace step 3 (mmmmaaaakkkkeeee) with mmmmaaaakkkkeeee ppppeeeerrrrllll and you will get a new
- _p_e_r_l binary with your extension linked in.
-
- See the _E_x_t_U_t_i_l_s::_M_a_k_e_M_a_k_e_r manpage for more details on building
- extensions. See also the next question.
-
- WWWWhhhhaaaatttt''''ssss tttthhhheeee ddddiiiiffffffffeeeerrrreeeennnncccceeee bbbbeeeettttwwwweeeeeeeennnn rrrreeeeqqqquuuuiiiirrrreeee aaaannnndddd uuuusssseeee????
-
- Perl offers several different ways to include code from one file into
- another. Here are the deltas between the various inclusion constructs:
-
- 1) do $file is like eval `cat $file`, except the former:
- 1.1: searches @INC and updates %INC.
- 1.2: bequeaths an *unrelated* lexical scope on the eval'ed code.
-
- 2) require $file is like do $file, except the former:
- 2.1: checks for redundant loading, skipping already loaded files.
- 2.2: raises an exception on failure to find, compile, or execute $file.
-
- 3) require Module is like require "Module.pm", except the former:
- 3.1: translates each "::" into your system's directory separator.
- 3.2: primes the parser to disambiguate class Module as an indirect object.
-
- 4) use Module is like require Module, except the former:
- 4.1: loads the module at compile time, not run-time.
- 4.2: imports symbols and semantics from that package to the current one.
-
- In general, you usually want use and a proper Perl module.
-
- HHHHoooowwww ddddoooo IIII kkkkeeeeeeeepppp mmmmyyyy oooowwwwnnnn mmmmoooodddduuuulllleeee////lllliiiibbbbrrrraaaarrrryyyy ddddiiiirrrreeeeccccttttoooorrrryyyy????
-
- When you build modules, use the PREFIX option when generating Makefiles:
-
- perl Makefile.PL PREFIX=/u/mydir/perl
-
- then either set the PERL5LIB environment variable before you run scripts
- that use the modules/libraries (see the _p_e_r_l_r_u_n manpage) or say
-
- use lib '/u/mydir/perl';
-
- See Perl's the _l_i_b manpage for more information.
-
- HHHHoooowwww ddddoooo IIII aaaadddddddd tttthhhheeee ddddiiiirrrreeeeccccttttoooorrrryyyy mmmmyyyy pppprrrrooooggggrrrraaaammmm lllliiiivvvveeeessss iiiinnnn ttttoooo tttthhhheeee mmmmoooodddduuuulllleeee////lllliiiibbbbrrrraaaarrrryyyy
- sssseeeeaaaarrrrcccchhhh ppppaaaatttthhhh????
-
- use FindBin;
- use lib "$FindBin::Bin";
- use your_own_modules;
-
-
-
-
-
-
- PPPPaaaaggggeeee 22220000
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111))))
-
-
-
- HHHHoooowwww ddddoooo IIII aaaadddddddd aaaa ddddiiiirrrreeeeccccttttoooorrrryyyy ttttoooo mmmmyyyy iiiinnnncccclllluuuuddddeeee ppppaaaatttthhhh aaaatttt rrrruuuunnnnttttiiiimmmmeeee????
-
- Here are the suggested ways of modifying your include path:
-
- the PERLLIB environment variable
- the PERL5LIB environment variable
- the perl -Idir commpand line flag
- the use lib pragma, as in
- use lib "$ENV{HOME}/myown_perllib";
-
- The latter is particularly useful because it knows about machine
- dependent architectures. The lib.pm pragmatic module was first included
- with the 5.002 release of Perl.
-
- AAAAUUUUTTTTHHHHOOOORRRR AAAANNNNDDDD CCCCOOOOPPPPYYYYRRRRIIIIGGGGHHHHTTTT
- Copyright (c) 1997, 1998 Tom Christiansen and Nathan Torkington. All
- rights reserved.
-
- When included as part of the Standard Version of Perl, or as part of its
- complete documentation whether printed or otherwise, this work may be
- distributed only under the terms of Perl's Artistic License. Any
- distribution of this file or derivatives thereof _o_u_t_s_i_d_e of that package
- require that special arrangements be made with copyright holder.
-
- Irrespective of its distribution, all code examples in this file are
- hereby placed into the public domain. You are permitted and encouraged
- to use this code in your own programs for fun or for profit as you see
- fit. A simple comment in the code giving credit would be courteous but
- is not required.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- PPPPaaaaggggeeee 22221111
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ8888((((1111))))
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- PPPPaaaaggggeeee 22222222
-
-
-
-
-
-
-